#include <time.h>
#include <math.h>

#include "sector.h"
#include "spaceShipName.h"

#define debugSector 1

/** \brief Créer un secteur
 *
 * \return sector*
 *
 */
sector* createSector()
{
    sector* sct;

    sct = (sector*) malloc(sizeof(sector));

    return sct;
}

/** \brief Initialiste le secteur
 *
 * \param sct sector*
 * \param numSector int
 * \return void
 *
 */
void initSector(sector *sct, int numSector)
{
    int i;

    sct->sizeX       = SIZEX;
    sct->sizeY       = SIZEY;
    sct->nbSpaceShip = 0;
    sct->nbFactory   = 0;
    sct->numSector   = numSector;
    sct->tabLaserSector = malloc(sizeof(TableauDynamiqueLaser));
    initialiserTabDynLaser(sct->tabLaserSector);

    for(i=0; i<numberSpaceShip; i++)
    {
        sct->tabSpaceShip[i] = NULL;
    }

    for(i=0; i<4; i++)
    {
        sct->tabGate[i] = malloc(sizeof(sectorGate));
        sct->tabGate[i]->status = 1;
    }
    sct->tabGate[0]->posX = 0;
    sct->tabGate[0]->posY = 280;

    sct->tabGate[1]->posX = 380;
    sct->tabGate[1]->posY = 0;

    sct->tabGate[2]->posX = 760;
    sct->tabGate[2]->posY = 280;

    sct->tabGate[3]->posX = 380;
    sct->tabGate[3]->posY = 560;


    /*if(debugSector == 1)
    {
        sct->hotSpot = (SDL_Rect**) malloc(SIZEX*sizeof(SDL_Rect*));
        for(i=0; i<SIZEY; i++)
        {
            sct->hotSpot[i] = (SDL_Rect*) malloc(SIZEY*sizeof(SDL_Rect));
        }

        for(i=0;i<SIZEX;i++)
        {
            for(j=0;j<SIZEY;j++)
            {
                sct->hotSpot[i][j].x = i;
                sct->hotSpot[i][j].y = j;
                sct->hotSpot[i][j].w = 1;
                sct->hotSpot[i][j].h = 1;
            }
        }
    }*/
}

/** \brief Free le secteur
 *
 * \param sct sector*
 * \return void
 *
 */
void freeSector(sector* sct)
{
    int i, nbSpaceShip, nbFactory;

    for(i=0; i<4; i++)
    {
        free(sct->tabGate[i]);
    }

    nbSpaceShip = sct->nbSpaceShip;
    for(i=0; i<nbSpaceShip; i++) /* on parcours le tableau de vaisseaux du secteur */
    {
        destroySpaceShip(sct->tabSpaceShip[i]); /* on detruit le ieme vaisseau du tableau */
    }

    nbFactory = sct->nbFactory;
    for(i=0; i<nbFactory; i++) /* on parcours le tableau de vaisseaux du secteur */
    {
        destroyFactory(sct->tabFactory[i]); /* on detruit le ieme vaisseau du tableau */
    }
}


/** \brief Free les lasers du secteur
 *
 * \param sct sector*
 * \return void
 *
 */
void freeSectorTDLaser(sector* sct)
{
    /*int i, j;*/

    testamentTabDynLaser(sct->tabLaserSector);
    free(sct->tabLaserSector);

   /* for(i=0; i<SIZEY; i++)
    {
        free(sct->hotSpot[i]);
    }
    free(sct->hotSpot);*/
}

/** \brief Initialiste les vaisseaux du secteur
 *
 * \param sct sector*
 * \param BDD_spaceShip spaceShip*
 * \param numSector int
 * \return void
 *
 */
void initSpaceShipSector(sector* sct, spaceShip* BDD_spaceShip, int numSector)
{
    srand(time(NULL));
    int randShip, i;
    sct->nbSpaceShip = rand() % (numberSpaceShip - 5) + 5;

    for(i=0; i<sct->nbSpaceShip; i++)
    {
        randShip = rand() % 2;
        sct->tabSpaceShip[i] = malloc(sizeof(spaceShip));

        initSpaceShip(sct->tabSpaceShip[i],
                        BDD_spaceShip[randShip].name,
                        BDD_spaceShip[randShip].hullCURRENT,
                        BDD_spaceShip[randShip].hullMAX,
                        BDD_spaceShip[randShip].shieldCURRENT,
                        BDD_spaceShip[randShip].shieldMAX,
                        BDD_spaceShip[randShip].speedCURRENT,
                        BDD_spaceShip[randShip].speedMAX,
                        BDD_spaceShip[randShip].accelerationCURRENT,
                        BDD_spaceShip[randShip].accelerationMAX,
                        BDD_spaceShip[randShip].cargoBaySize,
                        BDD_spaceShip[randShip].weaponSlot,
                        i,
                        BDD_spaceShip[randShip].cost,
                        BDD_spaceShip[randShip].caseBDD,
                        numSector);

        setShipPos(sct->tabSpaceShip[i], rand() % (SIZEX - sct->tabSpaceShip[i]->largeur), rand() % (SIZEY - sct->tabSpaceShip[i]->hauteur));
        /*showSpaceShipInfo(*(sct->tabSpaceShip[i]));*/
    }
}


/** \brief Initialise les factories du secteur
 *
 * \param sct sector*
 * \param tabFreight freight*
 * \param tabSpaceShip spaceShip*
 * \return void
 *
 */
void initFactorySector(sector* sct, freight* tabFreight, spaceShip* tabSpaceShip)
{
    srand(time(NULL));
    char aleaName[30];
    int i, aleaHull, aleaShield, aleaPosX, aleaPosY, aleaWeaponSlot, aleaCargoBaySize, randVar, ID;

    sct->nbFactory = rand() % (numberFactory - 2) + 2;
    /* ==================================================================
       initialise toutes les factory avec des caracteristiques aleatoires
       ================================================================== */
    for(i=0; i<sct->nbFactory; i++)
    {
        sct->tabFactory[i] = createFactory(); /* on fait un malloc pour chaque factory*/

        randVar = rand() % 2;
        strcpy(aleaName, spaceShipName[randVar]);
        strcpy(sct->tabFactory[i]->name, aleaName);
        aleaHull            = rand() % (5000 - 1000) + 1000;
        aleaShield          = rand() % (2000 - 500) + 500;
        aleaCargoBaySize    = rand() % (1000 - 100) + 100;
        aleaWeaponSlot      = rand() % 5;
        ID                  = i;

        sct->tabFactory[i] = createFactory();
        initFactory(sct->tabFactory[i], aleaName, aleaHull, aleaShield, aleaCargoBaySize, aleaWeaponSlot, ID);

        aleaPosX            = rand() % (SIZEX - sct->tabFactory[i]->largeur);
        aleaPosY            = rand() % (SIZEY - sct->tabFactory[i]->hauteur);
        setFactoryPos(sct->tabFactory[i], aleaPosX, aleaPosY);

     /* ==============================
        met le freight dans la factory
        ============================== */
        switch(sct->tabFactory[i]->factoryKind)
        {
            case(supplies) :
                addFactoryFreight(sct->tabFactory[i], &tabFreight[0]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[1]);
                break;
            case(tech) :
                addFactoryFreight(sct->tabFactory[i], &tabFreight[2]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[3]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[6]);
                break;
            case(pirateSlaves):
                addFactoryFreight(sct->tabFactory[i], &tabFreight[0]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[1]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[4]);
                break;
            case(pirateDrugs):
                addFactoryFreight(sct->tabFactory[i], &tabFreight[0]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[6]);
                addFactoryFreight(sct->tabFactory[i], &tabFreight[5]);
                break;
            case(garage):
                addFactorySpaceShip(sct->tabFactory[i], &tabSpaceShip[1]);
                addFactorySpaceShip(sct->tabFactory[i], &tabSpaceShip[2]);
                break;
            default:
                break;
        }
    }
}

/* \brief Version texte
 *
 * \param sct sector
 * \return void
 *
 */
void showSectorInfo(sector sct)
{
    int i;
    printf("Sector Info : \nSizeX %d  \nSizeY %d \n",
                            sct.sizeX,  sct.sizeY);
    printf("Spaceship id list : \n");
    for(i=0; i<sct.nbSpaceShip; i++)
    {
        printf("Space ship %d : %d\n", i, sct.tabSpaceShip[i]->ID);
    }
    printf("\n");
    printf("Factory id list : \n");
    for(i=0; i<sct.nbFactory; i++)
    {
        printf("Factory %d : %d\n", i, sct.tabFactory[i]->ID);
    }
    printf("\n");
}

/* \brief Obsolete
 *
 * \param sct sector*
 * \param p player
 * \return void
 *
 */
void changeGrid(sector* sct, player p)
{
    int i,j;

    for(i=0; i<sct->sizeX; i++)
    {
        for(j=0; j<sct->sizeY; j++)
        {
            sct->grid[i][j] = '.'; /* on place un point sur chaque case de la grille */
        }
    }
    for(i=0; i<sct->nbSpaceShip; i++) /* on parcours le tableau de vaisseaux */
    {
        sct->grid[sct->tabSpaceShip[i]->posX][sct->tabSpaceShip[i]->posY] = 'S'; /* on les place dans le secteur */
    }
    for(i=0; i<sct->nbFactory; i++)
    {
        sct->grid[sct->tabFactory[i]->posX][sct->tabFactory[i]->posY] = 'F';
    }
    for(i=0; i<p.nbOwnedSpaceShip; i++)
    {
        sct->grid[p.spaceShiplist[i]->posX][p.spaceShiplist[i]->posY] = 'C';
    }
    sct->grid[p.controlledSpaceShip->posX][p.controlledSpaceShip->posY] = 'P';
}

/* \brief Obsolete
 *
 * \param sct sector
 * \return void
 *
 */
void showGrid(sector sct)
{
    int i,j;

    for(i=0; i<sct.sizeX; i++) /* les dimensions du secteur doivent pas plus larges que la console */
    {
        for(j=0; j<sct.sizeY; j++) /* avec les 2 for on parcours l'ensemble de la grille */
        {
            printf("%c", sct.grid[j][i]); /* et on affiche le contenu de chaque case */
        }
        printf("\n");
    }
}

/* \brief Obsolète
 *
 * \param screen SDL_Surface*
 * \param sct sector
 * \return void
 *
 */
void SDL_ShowGrid(SDL_Surface* screen, sector sct)
{
   int i, j;
   SDL_Surface *playerShip=NULL, *sectorShip=NULL, *friendShip=NULL, *sectorFactory=NULL;
   SDL_Rect position;

   playerShip = SDL_LoadBMP("data/playerShip.bmp");
   friendShip = SDL_LoadBMP("data/friendShip.bmp");
   sectorShip = SDL_LoadBMP("data/sectorShip.bmp");
   sectorFactory = SDL_LoadBMP("data/sectorFactory.bmp");

   for(i=0; i<sct.sizeX; i++)
   {
        for(j=0; j<sct.sizeY; j++) /* avec les 2 for on parcours l'ensemble de la grille */
        {
           if(sct.grid[i][j] == 'P')
           {
                position.x = i*playerShip->w; /* mettre une taille de srpite en constante ?*/
                position.y = j*playerShip->h;
                SDL_BlitSurface(playerShip, NULL, screen, &position);
           }
           else if(sct.grid[i][j] == 'C')
           {
                position.x = i*playerShip->w; /* on a i*playerShip->w car une "case" fais la largeur d'une sprite*/
                position.y = j*playerShip->h;
                SDL_BlitSurface(friendShip, NULL, screen, &position);
           }
           else if(sct.grid[i][j] == 'F')
           {
                position.x = i*playerShip->w;
                position.y = j*playerShip->h;
                SDL_BlitSurface(sectorFactory, NULL, screen, &position);
           }
           else if(sct.grid[i][j] == 'S')
           {
                position.x = i*playerShip->w;
                position.y = j*playerShip->h;
                SDL_BlitSurface(sectorShip, NULL, screen, &position);
           }
        }
   }
    SDL_Flip(screen);

    SDL_FreeSurface(playerShip);
    SDL_FreeSurface(friendShip);
    SDL_FreeSurface(sectorFactory);
    SDL_FreeSurface(sectorShip);
}


/** \brief Affiche les éléments du secteur
 *
 * \param screen SDL_Surface*
 * \param sct sector
 * \param p player
 * \param boolBars int
 * \param playerShip SDL_Surface*
 * \param friendShip SDL_Surface*
 * \param sectorFactory SDL_Surface*
 * \param sectorShip SDL_Surface*
 * \param pirateShip SDL_Surface*
 * \param gate SDL_Surface*
 * \return void
 *
 */
void SDL_ShowSector(SDL_Surface* screen, sector sct, player p, int boolBars, SDL_Surface* playerShip, SDL_Surface* friendShip, SDL_Surface* sectorFactory, SDL_Surface* sectorShip, SDL_Surface* pirateShip, SDL_Surface* target, SDL_Surface* gate, SDL_Surface* background)
{
   int i;
   SDL_Rect position;

   position.x = 0;
   position.y = 0;
   SDL_BlitSurface(background, NULL, screen, &position);

    /* affichage vaisseaux IA */
    for(i=0; i<sct.nbSpaceShip; i++)
    {
        position.x = sct.tabSpaceShip[i]->posX;
        position.y = sct.tabSpaceShip[i]->posY;
        /*affichage en rouge si pirate */
        if(sct.tabSpaceShip[i]->spaceShipStatus == pirate)
        {
           SDL_BlitSurface(pirateShip, NULL, screen, &position);
        }
        /*affichage en blanc si pas pirate et pas cible de mission*/
        else if(sct.tabSpaceShip[i]->missionTarget == 1)
        {
            SDL_BlitSurface(sectorShip, NULL, screen, &position);
        }
        else
        {
            SDL_BlitSurface(target, NULL, screen, &position);
        }

        if(boolBars == 1)
        {
            showSpaceShipBars(screen, *(sct.tabSpaceShip[i]));
        }
    }
    /* affichage factory */
    for(i=0; i<sct.nbFactory; i++)
    {
        position.x = sct.tabFactory[i]->posX;
        position.y = sct.tabFactory[i]->posY;
        SDL_BlitSurface(sectorFactory, NULL, screen, &position);
    }
    /* affichage vaisseaux joueur */
    for(i=0; i<p.nbOwnedSpaceShip; i++)
    {
        if(p.spaceShiplist[i] != p.controlledSpaceShip) /* si c'est pas le vaisseau du joueur */
        {
            if(p.spaceShiplist[i]->numSector == sct.numSector) /* et qu'il fait partie du secteur */
            {
                position.x = p.spaceShiplist[i]->posX;
                position.y = p.spaceShiplist[i]->posY;
                SDL_BlitSurface(friendShip, NULL, screen, &position); /* on affiche l'image friendShip */
            }
        }
        else                                            /* sinon c'est le vaisseau controlle */
        {
            position.x = p.controlledSpaceShip->posX;
            position.y = p.controlledSpaceShip->posY;
            SDL_BlitSurface(playerShip, NULL, screen, &position); /* on affiche l'image playerShip */
        }
        if(boolBars == 1)
        {
            if(p.spaceShiplist[i]->numSector == sct.numSector)
            {
                showSpaceShipBars(screen, *(p.spaceShiplist[i]));
            }
        }
    }

    position.x = sct.tabGate[0]->posX;
    position.y = sct.tabGate[0]->posY;
    SDL_BlitSurface(gate, NULL, screen, &position);

    position.x = sct.tabGate[1]->posX;
    position.y = sct.tabGate[1]->posY;
    SDL_BlitSurface(gate, NULL, screen, &position);

    position.x = sct.tabGate[2]->posX;
    position.y = sct.tabGate[2]->posY;
    SDL_BlitSurface(gate, NULL, screen, &position);

    position.x = sct.tabGate[3]->posX;
    position.y = sct.tabGate[3]->posY;
    SDL_BlitSurface(gate, NULL, screen, &position);

    SDL_Flip(screen);
}


/* \brief Obsolète
 *
 * \param sct sector
 * \param x int
 * \param y int
 * \return char
 *
 */
char caseContent(sector sct, int x, int y)
{
    return sct.grid[x][y];
}


/** \brief Retourne la factory à la position x,y
 *
 * \param sct sector
 * \param x int
 * \param y int
 * \return factory*
 *
 */
factory* returnFactory(sector sct, int x, int y) /* retourne la factory situee a la position (x,y) ou NULL si il n'y a pas de factory*/
{
    int i;
    for(i=0; i<sct.nbFactory; i++)
    {
        if( (x>sct.tabFactory[i]->posX) && (x<sct.tabFactory[i]->posX + sct.tabFactory[i]->largeur) /* on verifie si on est dans l'usine en abscisse */
            && (y>sct.tabFactory[i]->posY) && (y<sct.tabFactory[i]->posY + sct.tabFactory[i]->hauteur)) /* on verifie en ordonnee */
        {
            return (sct.tabFactory[i]);
        }
    }
    return NULL;
}

/** \brief Renvoie le vaisseau du joueur
 *
 * \param p player
 * \param x int
 * \param y int
 * \return spaceShip*
 *
 */
spaceShip* returnPlayerSpaceShip(player p, int x, int y)
{
    int i;
    for(i=0; i<p.nbOwnedSpaceShip; i++)
    {
        if( (x>p.spaceShiplist[i]->posX) && (x<p.spaceShiplist[i]->posX + p.spaceShiplist[i]->largeur) /* on verifie si on est sur le vaisseau en abscisse */
            && (y>p.spaceShiplist[i]->posY) && (y<p.spaceShiplist[i]->posY + p.spaceShiplist[i]->hauteur)) /* on verifie en ordonnee */
        {
            return (p.spaceShiplist[i]);
        }
    }
    return NULL;
}


/** \brief Afficher les zones de danger (proche des vaisseaux)
 *
 * \param sct sector*
 * \param screen SDL_Surface*
 * \return void
 *
 */
void hotSpotSector(sector* sct, SDL_Surface* screen)
{
   /* int i, j, k, dist;

    for(i=0;i<800;i+=5)
    {
        for(j=0;j<600;j+=5)
        {
            sct->hotSpot[i][j].x = i;
            sct->hotSpot[i][j].y = j;
            sct->hotSpot[i][j].h = 3;
            sct->hotSpot[i][j].w = 3;

            for(k=0; k<sct->nbSpaceShip; k++)
            {
                dist = distance(
                                sct->hotSpot[i][j].x,
                                sct->hotSpot[i][j].y,
                                (sct->tabSpaceShip[k]->posX + 20),
                                (sct->tabSpaceShip[k]->posY + 20)
                                );
                if(dist < 80)
                {
                    SDL_FillRect(screen, &(sct->hotSpot[i][j]), SDL_MapRGB(screen->format, 255 - 3 * dist, 0, 0));
                }
            }
        }
    }*/
}


/** \brief Gère l'IA du secteur (déplacement, combat, évitement des collisions)
 *
 * \param sct sector*
 * \param p player
 * \param screen SDL_Surface*
 * \return void
 *
 */
void sectorIA(sector* sct, player p, SDL_Surface* screen)
{
    int i, j, k, factoryID, dist, dist2, dist3;
    waypoint wp, wp1, wp2;


    for(i=0; i<sct->nbSpaceShip; i++)/*déplacement des vaisseaux*/
    {

        /*================
        DEPLACEMENT SIMPLE
        ================*/

        for(j=0; j<sct->tabSpaceShip[i]->waypointTD->taille_utilisee; j++)
        {
            if(debugSector == 1)/*on affiche les points de passage*/
            {
                wp.wpRect.x = (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+1)).wpX - 5;
                wp.wpRect.y = (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+1)).wpY - 5;
                wp.wpRect.w = 10;
                wp.wpRect.h = 10;

                wp.spaceShipFlagRect.x = sct->tabSpaceShip[i]->posX + 40;
                wp.spaceShipFlagRect.y = sct->tabSpaceShip[i]->posY + 40;
                wp.spaceShipFlagRect.w = 8;
                wp.spaceShipFlagRect.h = 8;

                SDL_FillRect(screen, &(wp.wpRect), SDL_MapRGB(screen->format, ((i + 1) * 1234) % 255, ((i + 1) * 2345) % 255,((i + 1) * 3456) % 255));
                SDL_FillRect(screen, &(wp.spaceShipFlagRect), SDL_MapRGB(screen->format, ((i + 1) * 1234) % 255, ((i + 1) * 2345) % 255,((i + 1) * 3456) % 255));
            }
        }

        if(sct->tabSpaceShip[i]->waypointTD->taille_utilisee > 2)
        {
            for(j=0; j<sct->tabSpaceShip[i]->waypointTD->taille_utilisee - 2; j++)
            {
                /*on nettoie les points de passages, ne gardant que celui qui est le plus proche de la destination finale*/
                if(
                   (distance(valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpX, valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpY,
                   (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+1)).wpX, valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+1).wpY)
                   <=
                   (distance(valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpX, valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpY,
                   valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+2).wpX, valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+2).wpY)
                   ))
                   )
                {
                    supprimerElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+2);
                }
                else
                {
                    supprimerElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, j+1);
                }
            }
        }



        for(j=0;j<sct->nbSpaceShip;j++)
        {
            if(sct->tabSpaceShip[i]->spaceShipBehaviour == stealth)/*comportement discret*/
            {
                if(i!=j)
                {
                    dist = distance(
                            (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX,
                            (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY,
                            (sct->tabSpaceShip[j]->posX + 20),
                            (sct->tabSpaceShip[j]->posY + 20)
                        );

                    dist2 = distance(
                            sct->tabSpaceShip[i]->posX + 20,
                            sct->tabSpaceShip[i]->posY + 20,
                            (sct->tabSpaceShip[j]->posX + 20),
                            (sct->tabSpaceShip[j]->posY + 20)
                        );

                    dist3 = distance(
                            (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1)).wpX,
                            (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1)).wpY,
                            (sct->tabSpaceShip[j]->posX + 20),
                            (sct->tabSpaceShip[j]->posY + 20)
                        );

                    if(dist<80 || dist2<80 || dist3<80)/*si le point de passage est trop proche d'un autre vaisseau, on recalcule sa position*/
                    {
                        if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX + (pow(-1, rand()%2)) * (rand()%80) < 0)
                        {
                            wp1.wpX = 0;
                        }
                        else if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX + (pow(-1, rand()%2)) * (rand()%80)>800)
                        {
                            wp1.wpX = 800;
                        }
                        else
                        {
                            wp1.wpX = (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX + (pow(-1, rand()%2)) * (rand()%80);
                        }

                        if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY + (pow(-1, rand()%2)) * (rand()%80) < 0)
                        {
                            wp1.wpY = 0;
                        }
                        else if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY + (pow(-1, rand()%2)) * (rand()%80) > 600)
                        {
                            wp1.wpY = 600;
                        }
                        else
                        {
                            wp1.wpY = (valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY + (pow(-1, rand()%2)) * (rand()%80);
                        }

                        if(sct->tabSpaceShip[i]->waypointTD->taille_utilisee > 1)
                        {
                            modifierValeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp1, sct->tabSpaceShip[i]->waypointTD->taille_utilisee);
                        }
                        else
                        {
                            ajouterElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp1);
                        }
                    }
                }
            }
        }


        /*======================
        EVITEMENT DES COLLISIONS
        ======================*/

        if(sct->tabSpaceShip[i]->waypointTD->taille_utilisee <= 5)
        {
            for(j=i+1; j<sct->nbSpaceShip; j++)
            {
                if((distance(sct->tabSpaceShip[i]->posX + 20, sct->tabSpaceShip[i]->posY + 20, sct->tabSpaceShip[j]->posX + 20, sct->tabSpaceShip[j]->posY + 20)) < 40)
                {
                    if(sct->tabSpaceShip[i]->forceNewDestination == 0)/*on a 20 chances pour arriver à destination sinon, on force une nouvelle destination*/
                    {
                        supprimerElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1);
                        sct->tabSpaceShip[i]->forceNewDestination = 20;
                    }
                    else
                    {
                        sct->tabSpaceShip[i]->forceNewDestination --;
                    }

                    wp1.wpX = sct->tabSpaceShip[i]->posX + (sct->tabSpaceShip[i]->posX - sct->tabSpaceShip[j]->posX);
                    wp1.wpY = sct->tabSpaceShip[i]->posY + (sct->tabSpaceShip[i]->posY - sct->tabSpaceShip[j]->posY);
                    ajouterElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp1);

                    wp2.wpX = sct->tabSpaceShip[j]->posX + (sct->tabSpaceShip[j]->posX - sct->tabSpaceShip[i]->posX);
                    wp2.wpY = sct->tabSpaceShip[j]->posY + (sct->tabSpaceShip[j]->posY - sct->tabSpaceShip[i]->posY);
                    ajouterElementWaypointTabDyn(sct->tabSpaceShip[j]->waypointTD, wp2);
                }
            }
        }

        if(sct->tabSpaceShip[i]->waypointTD->taille_utilisee == 0)/*on est arrivé à destination*/
        {
            sct->tabSpaceShip[i]->forceNewDestination = 20;

            if(sct->tabSpaceShip[i]->wait == 0)
            {
                if(sct->tabSpaceShip[i]->spaceShipStatus == pirate)
                {
                    if(rand() % 1000 > 990)
                    {
                        sct->tabSpaceShip[i]->spaceShipBehaviour = combat;
                    }
                }

                sct->tabSpaceShip[i]->wait = rand() % 1000;

                switch(sct->tabSpaceShip[i]->spaceShipStatus)
                {
                    case(patrol) :
                        wp.wpX = rand() % (SIZEX - sct->tabSpaceShip[i]->largeur);
                        wp.wpY = rand() % (SIZEY - sct->tabSpaceShip[i]->hauteur);
                        ajouterElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp);
                        break;

                    case(pirate) :
                        wp.wpX = rand() % (SIZEX - sct->tabSpaceShip[i]->largeur);
                        wp.wpY = rand() % (SIZEY - sct->tabSpaceShip[i]->hauteur);
                        ajouterElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp);
                        break;

                    case(merchant) :
                        factoryID = rand() % (sct->nbFactory);
                        if((sct->tabSpaceShip[i]->posX != sct->tabFactory[factoryID]->posX) && (sct->tabSpaceShip[i]->posY != sct->tabFactory[factoryID]->posY))/*pour ne pas créer de trou noir*/
                        {
                            wp.wpX = sct->tabFactory[factoryID]->posX + 20 + (((sct->tabSpaceShip[i]->posX - sct->tabFactory[factoryID]->posX)/abs(sct->tabSpaceShip[i]->posX - sct->tabFactory[factoryID]->posX)) * (rand() % 20));
                            wp.wpY = sct->tabFactory[factoryID]->posY + 20 + (((sct->tabSpaceShip[i]->posY - sct->tabFactory[factoryID]->posY)/abs(sct->tabSpaceShip[i]->posY - sct->tabFactory[factoryID]->posY)) * (rand() % 20));
                        }
                        ajouterElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp);
                        break;
                }
            }
            else
            {
                sct->tabSpaceShip[i]->wait --;
            }
        }
        else
        {
            if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX == (sct->tabSpaceShip[i]->posX)
            && ((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY == (sct->tabSpaceShip[i]->posY)))
            {
                supprimerElementWaypointTabDyn( sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee );
            }
            else
            {
                if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX < (sct->tabSpaceShip[i]->posX)) /*on regarde où veut aller le vaisseau et on le déplace dans cette direction*/
                {
                    sct->tabSpaceShip[i]->posX --;
                }

                if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpX > (sct->tabSpaceShip[i]->posX))
                {
                    sct->tabSpaceShip[i]->posX ++;
                }

                if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY < (sct->tabSpaceShip[i]->posY))
                {
                    sct->tabSpaceShip[i]->posY --;
                }

                if((valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, sct->tabSpaceShip[i]->waypointTD->taille_utilisee)).wpY > (sct->tabSpaceShip[i]->posY))
                {
                    sct->tabSpaceShip[i]->posY ++;
                }
            }
        }


        /*==============
             COMBAT
        ==============*/

        if(sct->tabSpaceShip[i]->spaceShipBehaviour == combat)
        {
            if(sct->tabSpaceShip[i]->targetSpaceShip == 0)/*si l'on n'a pas de cible*/
            {
                if(sct->tabSpaceShip[i]->spaceShipStatus == pirate)
                {
                    if(rand() % sct->nbSpaceShip >= (sct->nbSpaceShip - 1))/*plus il y a de vaisseaux dans le secteur, moins le joueur a de chances de se faire engager par un pirate*/
                    {
                        sct->tabSpaceShip[i]->targetSpaceShip = -1;/*-1 désigne le joueur*/
                    }
                    else
                    {
                        if((k = rand() % sct->nbSpaceShip) == i)/*pour éviter que la cible ne soit le vaisseau lui-même*/
                        {
                            if(i == (sct->nbSpaceShip - 1))/*si c'est le dernier vaisseau dans le tableau*/
                            {
                                sct->tabSpaceShip[i]->targetSpaceShip = i-1;
                            }
                        }
                        else if(k != 0)
                        {
                            sct->tabSpaceShip[i]->targetSpaceShip = k;
                        }
                    }
                }
            }

            else if((sct->tabSpaceShip[i]->targetSpaceShip > 0) && (sct->tabSpaceShip[i]->targetSpaceShip < sct->nbSpaceShip)) /*la cible est une IA*/
            {
                if(sct->tabSpaceShip[i]->spaceShipStatus == pirate)
                {
                    if(distance(valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpX,
                        valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpY,
                         sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posX + 20,
                         sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posY + 20) > 50)
                    {
                        wp.wpX = sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posX + 20 + (pow(-1, rand()%2)) * (rand()%30 + 30);/*position autour du vaisseau cible*/
                        wp.wpY = sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posY + 20 + (pow(-1, rand()%2)) * (rand()%30 + 30);
                        modifierValeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp, 1);/*modifie la destination*/
                    }
                }
                /*on modifie les vecteurs du vaisseau, inutile pour les déplacements mais pas pour le combat puisqu'ils dirigent le laser*/
                sct->tabSpaceShip[i]->vectorX = (sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posX - sct->tabSpaceShip[i]->posX) / 100;
                sct->tabSpaceShip[i]->vectorY = (sct->tabSpaceShip[sct->tabSpaceShip[i]->targetSpaceShip]->posY - sct->tabSpaceShip[i]->posY) / 100;
            }


            else if(sct->tabSpaceShip[i]->targetSpaceShip == -1)/*si la cible est le joueur*/
            {
                if(distance(valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpX,
                        valeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, 1).wpY,
                         p.controlledSpaceShip->posX + 20,
                         p.controlledSpaceShip->posY + 20) > 50)
                {
                    wp.wpX = p.controlledSpaceShip->posX + 20 + (pow(-1, rand()%2)) * (rand()%30 + 30);/*position autour du vaisseau cible*/
                    wp.wpY = p.controlledSpaceShip->posY + 20 + (pow(-1, rand()%2)) * (rand()%30 + 30);
                    modifierValeurIemeElementWaypointTabDyn(sct->tabSpaceShip[i]->waypointTD, wp, 1);
                }
                /*on modifie les vecteurs du vaisseau, inutile pour les déplacements mais pas pour le combat puisqu'ils dirigent le laser*/
                sct->tabSpaceShip[i]->vectorX = (p.controlledSpaceShip->posX - sct->tabSpaceShip[i]->posX) / 100;
                sct->tabSpaceShip[i]->vectorY = (p.controlledSpaceShip->posY - sct->tabSpaceShip[i]->posY) / 100;
            }



            if((sct->tabSpaceShip[i]->weaponCoolDown == 0) && (sct->tabSpaceShip[i]->targetSpaceShip != 0))
            {
                ajouterElementTabDynLaser(sct->tabLaserSector, fireLaser(*(sct->tabSpaceShip[i])));
                sct->tabSpaceShip[i]->weaponCoolDown = rand() % 50 + 60;
                if(rand() % 1000 > 990)
                {
                    sct->tabSpaceShip[i]->spaceShipBehaviour = safe;
                    sct->tabSpaceShip[i]->targetSpaceShip = 0;
                }
            }
            else
            {
                sct->tabSpaceShip[i]->weaponCoolDown --;
            }
        }
    }
}

/** \brief Gère les évènements liés aux collisions
 *
 * \param sct sector*
 * \param p player*
 * \param explLaser explosion*
 * \return void
 *
 */
void collisionGlobal(sector* sct, player* p, explosion* explLaser)
{
    int i,j;

    /*============================
      Collision entre IA et joueur
      ============================*/
    for(i=0; i<sct->nbSpaceShip; i++)
    {
        if((distance(p->controlledSpaceShip->posX + 20, p->controlledSpaceShip->posY + 20, sct->tabSpaceShip[i]->posX + 20, sct->tabSpaceShip[i]->posY + 20)) < 30)
        {
            p->controlledSpaceShip->hullCURRENT -= 50;
            sct->tabSpaceShip[i]->hullCURRENT -= 50;
        }
        for(j=0; j<sct->tabLaserSector->taille_utilisee; j++)
        {
            if((distance(sct->tabSpaceShip[i]->posX + 20, sct->tabSpaceShip[i]->posY + 20, valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->posX + 10, valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->posY + 7)) < 20)
            {
                sct->tabSpaceShip[i]->spaceShipBehaviour = combat;
                sct->tabSpaceShip[i]->wait = 0;

                if(valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->firedBy == p->controlledSpaceShip)/*si le vaisseau ayant tiré le laser est celui du joueur*/
                {
                    sct->tabSpaceShip[i]->targetSpaceShip = -1;
                }
                else if(valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->firedBy->ID != i+1)
                {
                    sct->tabSpaceShip[i]->targetSpaceShip = valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->firedBy->ID;
                }

                sct->tabSpaceShip[i]->shieldCoolDown = 0;

                if(sct->tabSpaceShip[i]->shieldCURRENT > 0)
                {
                    sct->tabSpaceShip[i]->shieldCURRENT -= 100;
                }
                else
                {
                    sct->tabSpaceShip[i]->hullCURRENT -= 100;
                }

                explLaser->boolExplosion = 1;
                explLaser->posX = valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->posX;
                explLaser->posY = valeurIemeElementTabDynLaser(sct->tabLaserSector, j+1)->posY;

                supprimerElementTabDynLaser(sct->tabLaserSector, j+1);
            }
        }
    }

    for(i=0; i<sct->tabLaserSector->taille_utilisee; i++)
    {
        if((distance(p->controlledSpaceShip->posX + 20, p->controlledSpaceShip->posY + 20, valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posX + 10, valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posY + 7)) < 20)
         {
            p->controlledSpaceShip->shieldCoolDown = 0;

            if(p->controlledSpaceShip->shieldCURRENT > 0)
            {
                p->controlledSpaceShip->shieldCURRENT -= 100;
            }
            else
            {
                p->controlledSpaceShip->hullCURRENT -= 100;
            }
            explLaser->boolExplosion = 1;
            explLaser->posX = valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posX;
            explLaser->posY = valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posY;

            supprimerElementTabDynLaser(sct->tabLaserSector, i+1);
         }
    }
}

/** \brief Met à jour les lasers du secteur
 *
 * \param sct sector*
 * \return void
 *
 */
void updateSectorLaser(sector* sct)
{
    int i;
    for(i=0; i<(sct->tabLaserSector->taille_utilisee); i++)
    {
        updatePosLaser(valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1));

        if((valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posX<0) || (valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posY<0) ||
           (valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posX>800) || (valeurIemeElementTabDynLaser(sct->tabLaserSector, i+1)->posY>600)) /* si le laser sors de l'ecran... */
        {
            supprimerElementTabDynLaser(sct->tabLaserSector, i+1); /* ...on le supprime */
        }
    }
}

/** \brief Affiche les lasers du secteur
 *
 * \param screen SDL_Surface*
 * \param laserImg SDL_Surface*
 * \param sct sector
 * \return void
 *
 */
void printSectorLaser(SDL_Surface* screen, SDL_Surface* laserImg, sector sct)
{
    int i;
    for(i=0; i<(sct.tabLaserSector->taille_utilisee); i++)
    {
        SDL_printLaser(screen, laserImg, *(valeurIemeElementTabDynLaser(sct.tabLaserSector, i+1)));
    }
}

/** \brief Régénère le bouclier des vaisseaux dans le secteur
 *
 * \param sct sector*
 * \return void
 *
 */
void regenShieldSpaceShipSector(sector* sct)
{
    int i;
    for(i=0; i<sct->nbSpaceShip; i++)
    {
        regenShieldSpaceShip(sct->tabSpaceShip[i]);
    }
}

/** \brief Détruit les vaisseaux si besoin
 *
 * \param sct sector*
 * \param expl explosion*
 * \return void
 *
 */
void destroySpaceShipSector(sector* sct, player* p, explosion* expl)
{
    int i, j;

    i = 0;
    while(i<sct->nbSpaceShip)
    {
        if(sct->tabSpaceShip[i]->hullCURRENT<=0)
        {
            expl->boolExplosion = 1;
            expl->posX = sct->tabSpaceShip[i]->posX;
            expl->posY = sct->tabSpaceShip[i]->posY;

            if(sct->tabSpaceShip[i]->missionTarget == 0 && p->onMission == 0)
            {
                p->credits      = p->credits + 1000;
                p->onMission    = 1;
            }

            destroySpaceShip(sct->tabSpaceShip[i]);
            sct->nbSpaceShip--;
            for(j=i; j<sct->nbSpaceShip; j++)
            {
                sct->tabSpaceShip[j] = sct->tabSpaceShip[j+1];
            }
        }
        else
        {
            i++;
        }
    }
}

/** \brief Affiche une explosion
 *
 * \param screen SDL_Surface*
 * \param expl explosion*
 * \return void
 *
 */
void printExplosionSpaceShip(SDL_Surface* screen, explosion* expl)
{
    SDL_Surface *explosionSurface=NULL;
    SDL_Rect positionExplosion, etapeExplosion;

    explosionSurface = SDL_LoadBMP("data/explosionSpaceShip.bmp");
    SDL_SetColorKey(explosionSurface,  SDL_SRCCOLORKEY, SDL_MapRGB(explosionSurface->format, 255, 0, 255));

    positionExplosion.x = expl->posX;
    positionExplosion.y = expl->posY;

    etapeExplosion.x = 64*expl->etape;
    etapeExplosion.y = 0;
    etapeExplosion.w = 64;
    etapeExplosion.h = 64;

    expl->etape++;

    if(expl->etape > 14)
    {
        expl->boolExplosion = 0;
        expl->etape         = 0;
    }

    SDL_BlitSurface(explosionSurface, &etapeExplosion, screen, &positionExplosion);
    SDL_Flip(screen);

    SDL_FreeSurface(explosionSurface);
}

/** \brief Affiche une explosion
 *
 * \param screen SDL_Surface*
 * \param explLaser explosion*
 * \return void
 *
 */
void printExplosionLaser(SDL_Surface* screen, explosion* explLaser) /* a faire*/
{
    SDL_Surface *explosionSurface=NULL;
    SDL_Rect positionExplosion, etapeExplosion;

    explosionSurface = SDL_LoadBMP("data/explosionLaser.bmp");
    SDL_SetColorKey(explosionSurface,  SDL_SRCCOLORKEY, SDL_MapRGB(explosionSurface->format, 0, 0, 0));

    positionExplosion.x = explLaser->posX;
    positionExplosion.y = explLaser->posY;

    etapeExplosion.x = 23*explLaser->etape;
    etapeExplosion.y = 0;
    etapeExplosion.w = 23;
    etapeExplosion.h = 23;

    explLaser->etape++;

    if(explLaser->etape > 4)
    {
        explLaser->boolExplosion = 0;
        explLaser->etape         = 0;
    }

    SDL_BlitSurface(explosionSurface, &etapeExplosion, screen, &positionExplosion);
    SDL_Flip(screen);

    SDL_FreeSurface(explosionSurface);
}

/** \brief Changement de secteur à travers les portes, créer un secteur si besoin
 *
 * \param screen SDL_Surface*
 * \param gate SDL_Surface*
 * \param s spaceShip*
 * \param tabSector sector**
 * \param BDD_freight freight*
 * \param BDD_spaceShip spaceShip*
 * \return void
 *
 */
void starGate(SDL_Surface* screen, SDL_Surface* gate, spaceShip* s, sector** tabSector, freight* BDD_freight, spaceShip* BDD_spaceShip)
{
    /* porte ouest */
    if((s->numSector >= 1) &&
       (distance(s->posX+20,
                 s->posY+20,
                 tabSector[s->numSector]->tabGate[0]->posX+20,
                 tabSector[s->numSector]->tabGate[0]->posY+20)) < 20)
    {
        s->numSector--;
        s->posX = screen->w - gate->w - 20;
        s->posY = screen->h/2 - gate->h/2;
        s->vectorX   = 0;
        s->vectorY   = 0;
    }

    /* porte nord */
    else if((s->numSector >= 3) &&
       (distance(s->posX+20,
                 s->posY+20,
                 tabSector[s->numSector]->tabGate[1]->posX+20,
                 tabSector[s->numSector]->tabGate[1]->posY+20)) < 20)
    {
        s->numSector = s->numSector-3;  /* 3 = largeur d'une ligne */
        s->posX      = screen->w/2 - 20;
        s->posY      = screen->h - gate->h - 40;
        s->vectorX   = 0;
        s->vectorY   = 0;
    }

    /* porte est */
    else if((s->numSector <= 7) &&
       (distance(s->posX+20,
                 s->posY+20,
                 tabSector[s->numSector]->tabGate[2]->posX+20,
                 tabSector[s->numSector]->tabGate[2]->posY+20)) < 20)
    {
        s->numSector++;
        s->posX = gate->w + 10;
        s->posY = screen->h/2 - gate->h/2;
        s->vectorX   = 0;
        s->vectorY   = 0;
    }

    /*porte sud*/
    else if((s->numSector <= 5) &&
       (distance(s->posX+20,
                 s->posY+20,
                 tabSector[s->numSector]->tabGate[3]->posX+20,
                 tabSector[s->numSector]->tabGate[3]->posY+20)) < 20)
    {
        s->numSector = s->numSector+3;  /* 3 = largeur d'une ligne */
        s->posX = screen->w/2 - gate->w/2;
        s->posY = gate->h + 10;
        s->vectorX   = 0;
        s->vectorY   = 0;
    }

    if(tabSector[s->numSector] == NULL)
    {
        tabSector[s->numSector] = createSector();
        initSector(tabSector[s->numSector], s->numSector);
        initSpaceShipSector(tabSector[s->numSector], BDD_spaceShip, s->numSector);
        initFactorySector(tabSector[s->numSector], BDD_freight, BDD_spaceShip);
    }
}

void updateMission(player* p, sector* sct)
{
    if(sct->numSector == p->numSectorMission)
    {
        if(p->onMission == 0 && sct->tabSpaceShip[0] != NULL)
        {
            sct->tabSpaceShip[0]->missionTarget = 0;
        }
    }
}
